package com.yilijk.base.network.core;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.google.gson.Gson;
import com.yilijk.base.network.bean.BaseBean;
import com.yilijk.base.network.error.HttpErrorUtils;
import com.yilijk.base.network.https.HttpCallBack;
import com.yilijk.base.utils.ALog;
import com.yilijk.base.utils.StringUtils;

import org.json.JSONObject;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.util.Arrays;
import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by SHICHENG
 * <p>
 * Time on 2022/03/07
 */
public class NetworkCallback<T> implements Callback<ResponseBody> {

    private final HttpCallBack<T> httpCallback;

    public NetworkCallback( HttpCallBack<T> httpCallback) {
        this.httpCallback = httpCallback;
    }

    @Override
    public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> responseBody) {
        try {
            setResponse(responseBody);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {
        ALog.i(t.getMessage());
        // IOtException:Canceled
        // java.net.SocketException: Socket closed
        // okhttp3.internal.http2.StreamResetException: stream was reset: CANCEL
        // javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0x7b1efb9e88: I/O error during system call, Bad file descriptor
        //大部分情况为主动取消会抛出这两个异常
        //解绑不回调
        String message = t.getMessage();
        if (message != null) {
            ALog.i(message);
            List<String> cancelReasons = Arrays.asList("Canceled", "Socket closed", "stream was reset: CANCEL");
            if (cancelReasons.contains(message) || message.contains("SSL handshake aborted")) {
                try {
                    httpCallback.onComplete();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return;
            }
        }

        //请求失败回调
        try {
            httpCallback.onFailure(t.getMessage(), -1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            httpCallback.onComplete();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void setResponse(Response<ResponseBody> responseBody) {
        if (httpCallback != null) {
            int statusCode = responseBody.code();
            if (statusCode == 200) {
                Type type = httpCallback.getSuperclassTypeParameter();
                if (responseBody.body() != null) {
                    String str = "";
                    try {
                        str = responseBody.body().string();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    //默认code 200
                    int code = HttpURLConnection.HTTP_OK;
                    JSONObject object = null;
                    try {
                        object = new JSONObject(str);
                        if (object.has("code")) {
                            //有code用该值
                            code = object.optInt("code");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    T data = null;
                    if (type == String.class) {
                        //字符串
                        data = (T) str;
                    } else {
                        try {
                            //后端返回的数据类型不一致
                            data = new Gson().fromJson(str, type);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    //处理后端返回的数据类型不一致
                    if (data == null) {
                        Class<T> tClass = (Class<T>) type;
                        //新建对象
                        try {
                            data = tClass.newInstance();
                        } catch (IllegalAccessException | InstantiationException e) {
                            e.printStackTrace();
                        }
                        //重新设置返回值
                        if (data instanceof BaseBean) {
                            try {
                                if (object != null) {
                                    int baseCode = object.optInt("code");
                                    String baseMsg = object.optString("msg");
                                    BaseBean bean = (BaseBean) data;
                                    bean.setCode(baseCode);
                                    bean.setMsg(baseMsg);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    //vbp有的接口、其他没有code字段，也将成功返回
                    if (code == 200) {
                        try {
                            httpCallback.onSuccess(data, code);
                        } catch (Exception e) {
                            e.printStackTrace();
                            onFailure(e.getMessage(), statusCode);
                        }
                    } else {
                        try {
                            String message = "";
                            if (data instanceof BaseBean) {
                                message = ((BaseBean) data).getMsg();
                            }
                            if (TextUtils.isEmpty(message)){
                                httpCallback.onFailure(str, code);
                            }else{
                                httpCallback.onFailure(message, code);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            onFailure(e.getMessage(), statusCode);
                        }
                    }


                } else {
                    //body没有返回值
                    try {
                        Class<T> tClass = (Class<T>) type;
                        T data = tClass.newInstance();
                        httpCallback.onSuccess(data, statusCode);
                    } catch (Exception e) {
                        e.printStackTrace();
                        onFailure(e.getMessage(), statusCode);
                    }

                }

            } else {
                //网关非200
                String failureMessage = responseBody.message();
                failureMessage = StringUtils.isTrimEmpty(failureMessage) ? "网络错误" : failureMessage;
                failureMessage += "（ 错误代码: " + statusCode + " ）";
                onFailure(failureMessage, statusCode);
                HttpErrorUtils.switchCode(statusCode);
            }
            //完成
            try {
                httpCallback.onComplete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void onFailure(String failureMessage, int statusCode) {
        try {
            httpCallback.onFailure(failureMessage, statusCode);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
